﻿using System;
using System.Diagnostics;
using Reflector.CodeModel;

namespace CallGraphExtractor.CecilAdapter
{
    class Instruction : IInstruction
    {
        #region Fields

        private Mono.Cecil.Cil.Instruction mInstruction;

        #endregion Fields

        #region Lifecycle

        public Instruction(Mono.Cecil.Cil.Instruction instruction)
        {
            mInstruction = instruction;
        }

        #endregion Lifecycle

        #region Methods

        private object Adapt(object instructionOperand)
        {
            var mr = instructionOperand as Mono.Cecil.MethodReference;
            if (mr != null)
                return new MethodDeclaration(mr.Resolve());

            var fr = instructionOperand as Mono.Cecil.FieldReference;
            if (fr != null)
                return new FieldDeclaration(fr.Resolve());

            var pr = instructionOperand as Mono.Cecil.PropertyReference;
            if (pr != null)
                return new PropertyDeclaration(pr.Resolve());

            var er = instructionOperand as Mono.Cecil.EventReference;
            if (er != null)
                return new EventDeclaration(er.Resolve());

            if (instructionOperand != null)
                Debug.WriteLine(instructionOperand.ToString() + " instruction operand not adapted.");

            return null;
        }

        #endregion Methods

        #region IInstruction Members

        public int Code
        {
            get { return (int)mInstruction.OpCode.Code; }
            set { throw new NotSupportedException(); }
        }

        public int Offset
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public object Value
        {
            get { return Adapt(mInstruction.Operand); }//TODO cast and box
            set { throw new NotSupportedException(); }
        }

        #endregion
    }
}
